/**
 * @file a.cpp
 * @author your name (you@domain.com)
 * @brief 演示pthread_cancel无效问题
 * @version 0.1
 * @date 2022-08-17
 * 
 * @copyright Copyright (c) 2022
 * 
 * @note 默认情况下，pthread_cancel后，线程会继续正常执行，直到遇到cancel point才会退出。
 * cancel point包括：
 * 1. sleep
 * 2. std::this_thread::sleep_for
 * 3. printf
 * 4. pthread_testcancel
 * 5. std::cout
 * 加上pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, nullptr);可使线程立即退出
 * 
 * 注意事项：
 * 1. 使用std::cout作为cancel point会使cout状态异常，后续打印无法输出，不管是cout还是printf
 */

#include <iostream>
#include <thread>
#include <unistd.h>

pthread_t subthread;

void* thread_fun(void* arg)
{
    //pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, nullptr);
    while (1)
    {
        std::cout<< "sub delay start " << std::endl;
        for (int i = 0; i < 10000; i++)
        {
            for (int j = 0; j < 10000; j++)
            {

            }
        }
        
        //pthread_testcancel();     //ok
        //sleep(1);                 //ok
        //std::this_thread::sleep_for(std::chrono::milliseconds(1));    //ok
        //printf("sub delay done\n");                                   //ok
        std::cout<< "sub delay done" << std::endl;                    //not ok，会导致后面的打印都无输出，不管是cout还是printf
    }

    return NULL;
}


int main(void)
{
    int i = 0;
    while(1)
    {
        pthread_create(&subthread, NULL, thread_fun, NULL);
        std::this_thread::sleep_for(std::chrono::milliseconds(100));

        std::cout<< "111111111" << std::endl;
        pthread_cancel(subthread);
        std::cout<< "22222222" << std::endl;

        //cout的status在子线程退出后异常了
        printf("cout status = %d\n", std::cout.rdstate());
        pthread_join(subthread, nullptr);
        printf("cout status = %d\n", std::cout.rdstate());
        
        //std::cout.clear();            //如果不clear，后面的打印出不来
        std::cout<< "3333333333" << std::endl;
    
        std::cout<< "test cnt: " << ++i << std::endl;
    }
}
